<!--
 * @Description: 产品表单对话框组件 - 用于新增和编辑产品信息
 * @Author: lujq
 * @Date: 2024-12-21
 * @LastEditors: lujq
 * @LastEditTime: 2024-12-21 16:30:00
-->
<template>
  <el-dialog
    v-model="visible"
    :title="mode === 'add' ? '新增产品' : '编辑产品'"
    width="800px"
    :before-close="handleClose"
  >
    <el-form
      ref="formRef"
      :model="formData"
      :rules="formRules"
      label-width="100px"
      class="product-form"
    >
      <el-row :gutter="20">
        <!-- 基本信息 -->
        <el-col :span="24">
          <div class="form-section">
            <div class="section-title">基本信息</div>
            <el-row :gutter="20">
              <el-col :span="12">
                <el-form-item label="产品编码" prop="productCode">
                  <el-input
                    v-model="formData.productCode"
                    placeholder="请输入产品编码"
                    :disabled="mode === 'edit'"
                  />
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="产品名称" prop="name">
                  <el-input v-model="formData.name" placeholder="请输入产品名称" />
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="产品类别" prop="category">
                  <el-select
                    v-model="formData.category"
                    placeholder="请选择产品类别"
                    style="width: 100%"
                  >
                    <el-option label="真丝面料" value="silk" />
                    <el-option label="棉质面料" value="cotton" />
                    <el-option label="羊毛面料" value="wool" />
                    <el-option label="亚麻面料" value="linen" />
                    <el-option label="涤纶面料" value="polyester" />
                    <el-option label="混纺面料" value="blend" />
                  </el-select>
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="产品规格" prop="specification">
                  <el-input v-model="formData.specification" placeholder="请输入产品规格" />
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="单价(元/米)" prop="price">
                  <el-input-number
                    v-model="formData.price"
                    :min="0"
                    :precision="2"
                    :step="0.1"
                    style="width: 100%"
                    placeholder="请输入单价"
                  />
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="库存(米)" prop="stock">
                  <el-input-number
                    v-model="formData.stock"
                    :min="0"
                    :step="1"
                    style="width: 100%"
                    placeholder="请输入库存数量"
                  />
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="状态" prop="status">
                  <el-radio-group v-model="formData.status">
                    <el-radio label="active">上架</el-radio>
                    <el-radio label="inactive">下架</el-radio>
                  </el-radio-group>
                </el-form-item>
              </el-col>
            </el-row>
          </div>
        </el-col>

        <!-- 技术参数 -->
        <el-col :span="24">
          <div class="form-section">
            <div class="section-title">技术参数</div>
            <el-row :gutter="20">
              <el-col :span="12">
                <el-form-item label="材质成分">
                  <el-input v-model="formData.material" placeholder="请输入材质成分" />
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="幅宽">
                  <el-input v-model="formData.width" placeholder="请输入幅宽" />
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="克重">
                  <el-input v-model="formData.weight" placeholder="请输入克重" />
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="密度">
                  <el-input v-model="formData.density" placeholder="请输入密度" />
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="颜色">
                  <el-input v-model="formData.color" placeholder="请输入颜色" />
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="产地">
                  <el-input v-model="formData.origin" placeholder="请输入产地" />
                </el-form-item>
              </el-col>
            </el-row>
          </div>
        </el-col>

        <!-- 产品图片 -->
        <el-col :span="24">
          <div class="form-section">
            <div class="section-title">产品图片</div>
            <el-form-item label="产品图片">
              <div class="image-upload">
                <el-upload
                  class="image-uploader"
                  action="#"
                  :show-file-list="false"
                  :before-upload="beforeImageUpload"
                  :http-request="handleImageUpload"
                >
                  <img v-if="formData.image" :src="formData.image" class="uploaded-image" />
                  <el-icon v-else class="image-uploader-icon"><Plus /></el-icon>
                </el-upload>
                <div class="upload-tips">
                  <p>点击上传产品图片</p>
                  <p class="tips-text">支持 JPG、PNG 格式，文件大小不超过 2MB</p>
                </div>
              </div>
            </el-form-item>
          </div>
        </el-col>

        <!-- 产品描述 -->
        <el-col :span="24">
          <div class="form-section">
            <div class="section-title">产品描述</div>
            <el-form-item label="产品描述">
              <el-input
                v-model="formData.description"
                type="textarea"
                :rows="4"
                placeholder="请输入产品描述"
                maxlength="500"
                show-word-limit
              />
            </el-form-item>
          </div>
        </el-col>
      </el-row>
    </el-form>

    <template #footer>
      <div class="dialog-footer">
        <el-button @click="handleClose">取消</el-button>
        <el-button type="primary" :loading="loading" @click="handleSubmit">
          {{ mode === 'add' ? '新增' : '保存' }}
        </el-button>
      </div>
    </template>
  </el-dialog>
</template>

<script setup lang="ts">
import { ref, reactive, computed, watch } from 'vue'
import { ElMessage, type FormInstance, type FormRules, type UploadProps } from 'element-plus'
import { Plus } from '@element-plus/icons-vue'
import { createProduct, updateProduct } from '@/api/product'
import type { Product } from '@/types'

// 组件属性
interface Props {
  modelValue: boolean
  product: Product | null
  mode: 'add' | 'edit'
}

// 组件事件
interface Emits {
  (e: 'update:modelValue', value: boolean): void
  (e: 'success'): void
}

const props = defineProps<Props>()
const emit = defineEmits<Emits>()

// 表单引用
const formRef = ref<FormInstance>()

// 加载状态
const loading = ref(false)

// 对话框显示状态
const visible = computed({
  get: () => props.modelValue,
  set: (value: boolean) => emit('update:modelValue', value),
})

// 表单数据
const formData = reactive({
  productCode: '',
  name: '',
  category: '',
  specification: '',
  price: 0,
  stock: 0,
  status: 'active' as 'active' | 'inactive',
  material: '',
  width: '',
  weight: '',
  density: '',
  color: '',
  origin: '',
  image: '',
  description: '',
})

// 表单验证规则
const formRules: FormRules = {
  productCode: [
    { required: true, message: '请输入产品编码', trigger: 'blur' },
    { min: 3, max: 20, message: '产品编码长度在 3 到 20 个字符', trigger: 'blur' },
  ],
  name: [
    { required: true, message: '请输入产品名称', trigger: 'blur' },
    { min: 2, max: 50, message: '产品名称长度在 2 到 50 个字符', trigger: 'blur' },
  ],
  category: [{ required: true, message: '请选择产品类别', trigger: 'change' }],
  specification: [{ required: true, message: '请输入产品规格', trigger: 'blur' }],
  price: [
    { required: true, message: '请输入产品单价', trigger: 'blur' },
    { type: 'number', min: 0.01, message: '单价必须大于0', trigger: 'blur' },
  ],
  stock: [
    { required: true, message: '请输入库存数量', trigger: 'blur' },
    { type: 'number', min: 0, message: '库存数量不能小于0', trigger: 'blur' },
  ],
  status: [{ required: true, message: '请选择产品状态', trigger: 'change' }],
}

/**
 * 重置表单数据
 */
const resetFormData = () => {
  Object.assign(formData, {
    productCode: '',
    name: '',
    category: '',
    specification: '',
    price: 0,
    stock: 0,
    status: 'active',
    material: '',
    width: '',
    weight: '',
    density: '',
    color: '',
    origin: '',
    image: '',
    description: '',
  })
}

/**
 * 填充表单数据
 * @param {Product} product - 产品信息
 */
const fillFormData = (product: Product) => {
  Object.assign(formData, {
    productCode: product.productCode || '',
    name: product.name || '',
    category: product.category || '',
    specification: product.specification || '',
    price: product.price || 0,
    stock: product.stock || 0,
    status: product.status || 'active',
    material: product.material || '',
    width: product.width || '',
    weight: product.weight || '',
    density: product.density || '',
    color: product.color || '',
    origin: product.origin || '',
    image: product.image || '',
    description: product.description || '',
  })
}

/**
 * 图片上传前的验证
 * @param {File} file - 上传的文件
 * @returns {boolean} 是否通过验证
 */
const beforeImageUpload: UploadProps['beforeUpload'] = (file) => {
  const isJPGOrPNG = file.type === 'image/jpeg' || file.type === 'image/png'
  const isLt2M = file.size / 1024 / 1024 < 2

  if (!isJPGOrPNG) {
    ElMessage.error('只能上传 JPG/PNG 格式的图片!')
    return false
  }
  if (!isLt2M) {
    ElMessage.error('图片大小不能超过 2MB!')
    return false
  }
  return true
}

/**
 * 处理图片上传
 * @param {any} options - 上传选项
 */
const handleImageUpload = (options: any) => {
  const { file } = options

  // 创建 FileReader 来读取文件
  const reader = new FileReader()
  reader.onload = (e) => {
    formData.image = e.target?.result as string
  }
  reader.readAsDataURL(file)
}

/**
 * 处理表单提交
 */
const handleSubmit = async () => {
  if (!formRef.value) return

  try {
    await formRef.value.validate()
    loading.value = true

    const productData = {
      ...formData,
      sales: props.mode === 'add' ? 0 : props.product?.sales || 0,
      orderCount: props.mode === 'add' ? 0 : props.product?.orderCount || 0,
      customerCount: props.mode === 'add' ? 0 : props.product?.customerCount || 0,
    }

    if (props.mode === 'add') {
      await createProduct(productData)
      ElMessage.success('产品新增成功')
    } else {
      await updateProduct(props.product!.id, productData)
      ElMessage.success('产品更新成功')
    }

    emit('success')
    handleClose()
  } catch (error) {
    console.error('提交失败:', error)
    ElMessage.error(props.mode === 'add' ? '新增失败' : '更新失败')
  } finally {
    loading.value = false
  }
}

/**
 * 处理关闭对话框
 */
const handleClose = () => {
  formRef.value?.resetFields()
  resetFormData()
  visible.value = false
}

// 监听产品变化，填充表单数据
watch(
  () => [props.product, props.mode, visible.value],
  () => {
    if (visible.value) {
      if (props.mode === 'edit' && props.product) {
        fillFormData(props.product)
      } else {
        resetFormData()
      }
    }
  },
  { immediate: true },
)
</script>

<style scoped>
.product-form {
  max-height: 60vh;
  overflow-y: auto;
  padding-right: 8px;
}

.form-section {
  margin-bottom: 24px;
  padding: 16px;
  border: 1px solid #ebeef5;
  border-radius: 6px;
  background: #fafafa;
}

.section-title {
  font-size: 16px;
  font-weight: 600;
  color: #303133;
  margin-bottom: 16px;
  padding-bottom: 8px;
  border-bottom: 1px solid #ebeef5;
}

.image-upload {
  display: flex;
  align-items: flex-start;
  gap: 16px;
}

.image-uploader {
  border: 1px dashed #d9d9d9;
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  transition: border-color 0.3s;
}

.image-uploader:hover {
  border-color: #409eff;
}

.image-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 120px;
  height: 120px;
  text-align: center;
  line-height: 120px;
}

.uploaded-image {
  width: 120px;
  height: 120px;
  display: block;
  object-fit: cover;
}

.upload-tips {
  flex: 1;
}

.upload-tips p {
  margin: 0 0 8px 0;
  color: #606266;
}

.tips-text {
  font-size: 12px;
  color: #909399;
}

.dialog-footer {
  text-align: right;
}

/* 滚动条样式 */
.product-form::-webkit-scrollbar {
  width: 6px;
}

.product-form::-webkit-scrollbar-track {
  background: #f1f1f1;
  border-radius: 3px;
}

.product-form::-webkit-scrollbar-thumb {
  background: #c1c1c1;
  border-radius: 3px;
}

.product-form::-webkit-scrollbar-thumb:hover {
  background: #a8a8a8;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .image-upload {
    flex-direction: column;
  }

  .image-uploader-icon,
  .uploaded-image {
    width: 100px;
    height: 100px;
    line-height: 100px;
  }
}
</style>
